#pragma once

#include <iostream>
#include <memory>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

namespace ns_server{
    enum{
        SOCKET_ERR = 1,
        BIND_ERR
    };

    const static uint16_t default_port = 8086;

    class UdpServer{
        public:
            UdpServer(std::string ip, uint16_t port = default_port):ip_(ip), port_(port){
                std::cout << "server addr: " << ip << " : " << port_ << std::endl;
            }

            void InitServer(){
                //1.创建socket接口，打开网络文件
                sock_ = socket(AF_INET, SOCK_DGRAM, 0);
                if(sock_ < 0){
                    std::cerr << "creat socket error: " << strerror(errno) << std::endl;
                    exit(SOCKET_ERR);
                }
                std::cout << "creat socket success: " << sock_ << std::endl;

                //2.给服务器知名IP地址和端口port
                struct sockaddr_in local;
                bzero(&local, sizeof(local));

                local.sin_family = AF_INET;
                local.sin_port = htons(port_);
                local.sin_addr.s_addr = inet_addr(ip_.c_str());//inet_addr函数
                //2.1将字符串IP转化为4字节int
                //2.2将主机序列转化为网络序列

                //3.bind
                if(bind(sock_, (struct sockaddr*)&local, sizeof(local)) < 0){
                    std::cerr << "bind socket error: " << strerror(errno) << std::endl;
                    exit(BIND_ERR);
                }
                std::cout << "bind socket success: " << sock_ << std::endl;
            }

            void Start(){

            }

            ~UdpServer(){

            }
        private:
            int sock_;//网络文件描述符
            uint16_t port_;//端口号
            std::string ip_;//ip号
    };
}